<template>
  <div>
    <div class="d-flex justify-content-between">
      <h4 class="archive-title">附件信息</h4>
      <div>
        <input type="file" ref="uploadInput" class="d-none" multiple />
        <el-button v-if="!viewMode" type="text" class="py-0" @click="handleUpload">上传</el-button>
        <el-button type="text" class="py-0" @click="handleDownloadAll">批量下载</el-button>
      </div>
    </div>
    <table class="table table-bordered table-sm">
      <colgroup>
        <col width="20%" />
        <col width="30%" />
        <col width="20%" />
        <col width="30%" />
      </colgroup>
      <tbody>
        <tr>
          <td class="bg-light">附件编号</td>
          <td class="bg-light">附件名称</td>
          <td class="bg-light">上传时间</td>
          <td class="bg-light">操作</td>
        </tr>
        <tr v-for="(file, index) in uploadFiles" :key="index">
          <td>{{ index + 1 }}</td>
          <td>{{ file.name }}</td>
          <td>{{ file.time }}</td>
          <td class="p-0" style="position: relative">
            <div v-show="loading" class="btn-percent" :style="`width:${file.percent}%`"></div>
            <div class="mt-1 ml-1">
              <el-button
                type="text"
                class="py-0"
                :disabled="loading"
                @click="handleDownloadUpload(index)"
              >
                下载
              </el-button>
              <el-button
                type="text"
                class="py-0"
                v-if="!viewMode"
                :disabled="loading"
                @click="handleDeleteUpload(index)"
              >
                删除
              </el-button>
            </div>
          </td>
        </tr>
        <tr v-for="(file, index) in areadyFiles" :key="`a-${index}`">
          <td>{{ uploadLength + index + 1 }}</td>
          <td>{{ file.name }}</td>
          <td>{{ file.time }}</td>
          <td>
            <el-button
              type="text"
              class="py-0"
              :disabled="loading"
              @click="handleDownloadAready(index)"
            >
              下载
            </el-button>
            <el-button
              type="text"
              class="py-0"
              v-if="!viewMode"
              :disabled="loading"
              @click="handleDeleteAready(index)"
            >
              删除
            </el-button>
          </td>
        </tr>
        <tr v-if="allLength === 0">
          <td colspan="4" class="text-center text-muted">
            <i class="el-icon-loading" v-if="attachLoading"></i>
            <div class="p-2" v-else>暂无附件</div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { dateFormat, downloadByLink, stringFileName, isNumberString } from '@vimi/utils-tool'
import { uploadOss } from '@/common/api/oss'
import { exportUrl } from '@/common/api/download'

export default {
  components: {},
  props: {
    visible: Boolean,
    formData: {
      type: Object,
      default: () => ({}),
    },
    viewMode: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      loading: false,
      attachLoading: false,
      areadyFiles: [],
      uploadFiles: [],
      ossDeleteFiles: [],
      tableName: 'project_archives_detail',

      // 重名提示
      sameNameFiles: [],
      sameNameVisible: false,

      // 加序号
      nextDir: 1,
    }
  },
  computed: {
    ...mapGetters(['userId']),
    archiveId() {
      return this.formData.project_archives_id
    },
    areadyLength() {
      return this.areadyFiles.length
    },
    uploadLength() {
      return this.uploadFiles.length
    },
    allLength() {
      return this.areadyLength + this.uploadLength
    },
  },
  watch: {
    visible: {
      handler: function (val) {
        if (val) {
          this.getAttach()
        }
      },
      immediate: true,
    },
  },
  created() {},
  mounted() {
    this.bindChangeListener()
  },
  methods: {
    beforeClose() {
      this.$emit('update:visible', false)
    },

    getAttach() {
      this.uploadFiles = []
      this.areadyFiles = []
      this.ossDeleteFiles = []

      const { uploadInput } = this.$refs
      if (uploadInput) {
        uploadInput.value = ''
      }

      const { archiveId } = this
      if (!archiveId) {
        return
      }

      this.attachLoading = true
      this.$api
        .getData(
          this.$serviceName,
          this.tableName,
          {
            'project_archives_id.eq': archiveId,
          },
          {
            create_time: 'desc',
          }
        )
        .then(res => {
          const data = res?.data ?? []
          this.areadyFiles = data.map(it => {
            const { attachment = '' } = it

            // 获取所有上一级文件夹
            const preDir = attachment.replace(/.*\/(.*)\/(.*)?$/, '$1')
            if (isNumberString(preDir)) {
              const currIndex = +preDir || 0
              if (currIndex >= this.nextDir) {
                this.nextDir++
              }
            }

            return {
              ...it,
              name: stringFileName(attachment),
              time: it.create_time,
            }
          })
        })
        .finally(() => {
          this.attachLoading = false
        })
    },

    changeListener(e) {
      const { files = [] } = e.target
      const time = dateFormat(new Date())

      // 把文件存入数组中
      const selectedFiles = []
      for (let i = 0; i < files.length; i++) {
        const file = files[i]
        selectedFiles.push({
          id: `upload-${i}`,
          file,
          name: file.name,
          time,
          percent: 0,
        })
      }

      // 检查是否有相同名字的文件(直接覆盖)
      for (let i = 0; i < this.uploadFiles.length; i++) {
        const file = this.uploadFiles[i]
        const sameIndex = selectedFiles.findIndex(it => it.name === file.name)
        if (sameIndex > -1) {
          this.uploadFiles[i] = selectedFiles[sameIndex]
          selectedFiles.splice(sameIndex, 1)
        }
      }

      this.uploadFiles.push(...selectedFiles)
    },

    bindChangeListener() {
      const { uploadInput } = this.$refs
      uploadInput.addEventListener('change', this.changeListener.bind(this))
    },

    offChangeListener() {
      const { uploadInput } = this.$refs
      if (!uploadInput) return
      uploadInput.removeEventListener('change', this.changeListener.bind(this))
    },

    handleUpload() {
      const { uploadInput } = this.$refs
      uploadInput.click()
    },

    // 删除
    handleDeleteUpload(index) {
      this.$utils
        .msgbox({
          message: '确定删除此附件?',
          beforeClose: () => this.uploadFiles.splice(index, 1),
        })
        .then(() => {
          // this.$message.success('删除成功！')
        })
        .catch(() => this.$message.error('删除失败，请重试！'))
    },

    handleDeleteAready(index) {
      const url = this.areadyFiles[index].attachment
      this.$utils
        .msgbox({
          message: '确定删除此附件?',
          beforeClose: () => this.areadyFiles.splice(index, 1),
        })
        .then(() => {
          this.ossDeleteFiles.push(url)
          // this.$message.success('删除成功！')
        })
        .catch(() => this.$message.error('删除失败，请重试！'))
    },

    // 下载
    handleDownloadUpload(index) {
      const { file } = this.uploadFiles[index]
      const { name, type } = file
      const url = window.URL.createObjectURL(new Blob([file]), { type })
      downloadByLink({ url, filename: name })
      window.URL.revokeObjectURL(url)
    },

    handleDownloadAready(index) {
      const { attachment: url } = this.areadyFiles[index]
      exportUrl({
        url,
        filename: stringFileName(url),
      })
    },

    handleDownloadAll() {
      if (this.allLength === 0) {
        return this.$message.error('没有附件可以下载')
      }
      this.uploadFiles.forEach((_, index) => {
        this.handleDownloadUpload(index)
      })
      this.areadyFiles.forEach((_, index) => {
        this.handleDownloadAready(index)
      })
    },

    // 提交
    submit() {
      const res = this.areadyFiles.map(it => ({
        id: it.id,
        attachment: it.attachment,
        create_time: it.create_time,
      }))

      if (!this.uploadFiles.length) {
        return Promise.resolve({
          files: res,
          deleteFiles: this.getDeleteFiles(res),
          addFiles: [],
        })
      }

      const promises = this.uploadFiles.map(it =>
        uploadOss({
          file: it.file,
          dir: `credit/archive/${this.formData.customer_related_id}/${this.nextDir}`,
          type: 0, // 用文件名
          progress: e => (it.percent = e.percent),
        })
      )

      this.loading = true
      return Promise.all(promises)
        .then(list => {
          list.forEach(it =>
            res.push({
              attachment: it,
            })
          )

          return {
            files: res,
            deleteFiles: this.getDeleteFiles(res),
            addFiles: list,
          }
        })
        .finally(() => {
          this.loading = false
        })
    },

    // 删除的附件
    getDeleteFiles(res) {
      return this.ossDeleteFiles.filter(it => !res.find(item => item.attachment === it))
    },
  },

  beforeDestroy() {
    this.offChangeListener()
  },
}
</script>

<style lang="scss" scoped>
.archive-title {
  font-size: 1.1rem;
  font-weight: bold;
}
.btn-percent {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  background-color: rgba(128, 128, 128, 0.2);
}
</style>
